package com.algo.config;

import com.algo.color.Black;
import com.algo.color.Light;
import com.algo.color.White;
import com.algo.conditional.ConditionalOnExistClass;
import com.algo.model.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;

// congiguration表明这是一个配置类
@Configuration
// ComponentScan配置扫描的路径，excludeFilters可以设置扫描拦截器
@ComponentScan(value = "com.algo", excludeFilters = {
                /*@Filter(type = FilterType.ANNOTATION, value = Controller.class),
                @Filter(type = FilterType.ASSIGNABLE_TYPE, value = UserService.class),*/
                /*@Filter(type = FilterType.CUSTOM, value = MyTypeFilter.class)*/
        }/*, includeFilters = {
                @Filter(type = FilterType.CUSTOM, value = MyTypeFilter.class)
        },*/
        /**
         * 注意点：useDefaultFilters 设置成false，则Controller\Service\Repository\Component 注解的bean都不会被管理
         */
        // useDefaultFilters = false
)

// Spring还提供了一种通过 @Import 方式向Spring中添加需要管理的 bean
// Import支持三种方式
// 第一种：通过简单的 AAA.class直接向Spring中添加一个bean，其中bean的id为AAA类的全限定名
// 第二种：自定义 ImportSelector接口的实现类，通过返回类的全限定名，批量向Spring容器添加 bean
// 第三种：自定义 ImportBeanDefinitionRegistrar 接口的实现类，向 BeanDefinitionRegistry 添加 bean定义
@Import({Black.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfigOfRegister {

    @Bean
    public User user() {
        return new User("kubi", 26);
    }


//     可以通过 @Configuration 标明这是一个注解类，并通过 @Bean 方式交给Spring容器管理，
//                  一般通过 @Bean的方式都是为了配置第三方jar包内的类
//     自己项目的类，可以通过 @ComponentScan 的方式批量交给Spring去管理，
//                  可以通过 excludeFilters和 includeFilters 添加或过滤特殊处理的类

//    Spring还提供了另外一种方式，通过使用 @Import注解，向容器中添加 bean，一般使用这种也是引入第三方的类的时候使用

//    @Import支持三种方式
//        第一种：通过简单的 AAA.class直接向Spring中添加一个bean，其中bean的id为AAA类的全限定名
//        第二种：自定义 ImportSelector接口的实现类，通过返回类的全限定名，批量向Spring容器添加 bean
//        第三种：自定义 ImportBeanDefinitionRegistrar 接口的实现类，向 BeanDefinitionRegistry 添加 bean定义



    /**
     * 声明为 @Lazy后，单例的bean将会采用懒加载的方式，只有第一次使用的地方才会触发加载
     *
     * @Scope("prototype") 申明为多实例，每次 getBean都会返回新的实例
     */
    @Bean
    @Lazy
    // @Scope("prototype")
    public White white() {
        return new White();
    }

    @Bean
    @ConditionalOnExistClass(White.class)
    public Light light() {
        return new Light();
    }

}
